package com.yuneec.fly.utils;

import android.content.Context;
import android.location.Location;

import com.yuneec.droneservice.model.ControllerLocation;
import com.yuneec.fly.GlobalParams;
import com.yuneec.fly.R;
import com.yuneec.fly.presenters.ConstantPresenter;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by jw.gu on 2016/6/20.
 */
public class LocationUtils {
    public static String UNIT_METER = "m";
    public static String UNIT_KELOMETER = "km";
    public static String UNIT_FEET = "ft";
    public static String UNIT_MILE = "mi";
    public static String UNIT_METER_PER_HOUR = "m/s";
    public static String UNIT_KELOMETER_PER_HOUR = "km/h";
    public static String UNIT_MILE_PER_HOUR = "mi/h";
    public static float CONVERSION_MTR_TO_FT = 3.2808f; // 1mtr = 3.2808ft
    public static float CONVERSION_MI_TO_FT = 5280f; // 1mi = 5280ft
    public static float CONVERSION_MPS_TO_KPH = 3.6f; //  1m/s =  3.6km/h
    public static float CONVERSION_MPS_TO_MPH = 2.2369f; // 1mtr/s = 2.2369mi/h
    public static final int UNIT_METRIC = 1;

    /**
     * 获取航线总长度
     *
     * @return
     */
//    public static double getTotalPointsDistance() {
//        if (GlobalParams.waypoints.size() <= 1) {
//            return 0;
//        }
//        float totalDistance = 0;
//        for (int i = 0; i < GlobalParams.waypoints.size() - 1; i++) {
//            totalDistance += calculateDistanceAndBearing(GlobalParams.waypoints.get(i).getLatitude(), GlobalParams.waypoints.get(i).getLongitude(), GlobalParams.waypoints.get(i).getHeight()
//                    , GlobalParams.waypoints.get(i + 1).getLatitude(), GlobalParams.waypoints.get(i + 1).getLongitude(), GlobalParams.waypoints.get(i+1).getHeight())[0];
//        }
//        return totalDistance;
//    }

    /**
     * 判断是否有航点离遥控器当前位置超过1公里
     * @return
     * @param pointFarawayLimitMeter
     */
//    public static List<Integer> checkPointsDistanceLimit(int pointFarawayLimitMeter) {
//        List<Integer> indexes = new ArrayList<Integer>();
//        if (GlobalParams.waypoints.size() <= 1) {
//            return indexes;
//        }
//        for (int i = 0; i < GlobalParams.waypoints.size(); i++) {
//            if (calculateDistanceAndBearing(GlobalParams.waypoints.get(i).getLatitude(), GlobalParams.waypoints.get(i).getLongitude(), 0
//                    , GlobalParams.controllerLocation.latitude, GlobalParams.controllerLocation.longitude, 0)[0] > pointFarawayLimitMeter) {
//                indexes.add(i);
//            }
//        }
//        return indexes;
//    }


    /**
     * 计算遥控器和飞机之间的距离
     *
     * @return
     */
    public static float getDistanceBetweenControllerAndDrone() {
        ControllerLocation location = ConstantPresenter.getInstance().getControllerLocation();
        if (GlobalParams.droneFeedback == null || location == null) {
            return -1;
        }
        return calculateDistanceAndBearing(location.latitude, location.longitude, 0
                , GlobalParams.droneFeedback.latitude, GlobalParams.droneFeedback.longitude, 0)[0];
    }


    /**
     * 计算两点间的距离
     *
     * @return
     */
    public static float getDistanceBetweenTwoPoint(double latitude1, double longitude1, double latitude2, double longitude2) {
        return calculateDistanceAndBearing(latitude1, longitude1, 0
                , latitude2, longitude2, 0)[0];
    }

    public static String formatLengthDisplayString(Context context, float lengthMetric) {
        String displayLengthUnit = getDisplayLengthUnit();
        // lengthMetric : m
        float length = getDisplayLengthUnit().equals(UNIT_METER) ? lengthMetric : (lengthMetric * CONVERSION_MTR_TO_FT);
        return context.getResources().getString(R.string.drone_info_value, length, displayLengthUnit);
    }

    public static String formatLengthDisplayIntegerString(Context context, int lengthMetric) {
        String displayLengthUnit = getDisplayLengthUnit();
        // lengthMetric : m
        float length = getDisplayLengthUnit().equals(UNIT_METER) ? lengthMetric : (lengthMetric * CONVERSION_MTR_TO_FT);
        return context.getResources().getString(R.string.drone_info_int_value, (int) length, displayLengthUnit);
    }

    public static String formatVelocityDisplayString(Context context, float velocityMetric) {
        String displayVelocityUnit = getDisplayVelocityUnit();
        // velocityMetric : m/s
        float velocity = displayVelocityUnit.equals(UNIT_KELOMETER_PER_HOUR) ? velocityMetric * CONVERSION_MPS_TO_KPH : (velocityMetric * CONVERSION_MPS_TO_MPH);
        return context.getResources().getString(R.string.drone_info_value, velocity, displayVelocityUnit);
    }

    public static String formatHomeDistanceDisplayString(Context context, float distanceMetric) {
        float distance;
        String unit;
        if (UNIT_METRIC == GlobalParams.velocityUnit) {
            distance = distanceMetric;
            unit = UNIT_METER;
            if (distance >= 10000) {
                distance /= 1000;
                unit = UNIT_KELOMETER;
            }
        } else {
            distance = distanceMetric * CONVERSION_MTR_TO_FT;
            unit = UNIT_FEET;
            if (distance >= 10000) {
                distance /= CONVERSION_MI_TO_FT;
                unit = UNIT_MILE;
            }
        }
        return context.getResources().getString(R.string.drone_info_value, distance, unit);
    }

    public static String getDisplayLengthUnit() {
        return (GlobalParams.velocityUnit == UNIT_METRIC) ? UNIT_METER : UNIT_FEET;
    }

    public static String getDisplayVelocityUnit() {
        return (GlobalParams.velocityUnit == UNIT_METRIC) ? UNIT_KELOMETER_PER_HOUR : UNIT_MILE_PER_HOUR;
    }

    public static float[] calculateDistanceAndBearing(double startLatitude, double startLongitude, float startAltitude,
                                                      double endLatitude, double endLongitude, float endAltitude) {
        float[] result = new float[2];
        if ((startLatitude == 0 && startLongitude == 0)
                || (endLatitude == 0 && endLongitude == 0)) {
            result[0] = -1;
            result[1] = -1;
        }
        Location.distanceBetween(startLatitude, startLongitude, endLatitude, endLongitude, result);
        if (endAltitude - startAltitude > 0) {
            result[0] = (float) Math.sqrt(Math.pow(result[0], 2) + Math.pow((endAltitude - startAltitude), 2));
        }
        if (result[1] < 0) {
            result[1] += 360;
        }
        return result;
    }
}
